﻿using System;
using Aricie.Collections;
using Aricie.ComponentModel;
using Aricie.DNN.UI.Attributes;
using DotNetNuke.UI.WebControls;
using StackExchange.Redis;

namespace Aricie.DNN.Caching.Client.RedisCachingProvider
{

    public enum RedisCallbackMode
    {
        CustomChannel,
        KeyspaceNotifications
    }


    public class RedisClusterSettings : CachingClusterSettings
    {


        public RedisClusterSettings()
        {
            ClientName = "DNN Redis Client";
            DbNumber = 0;
            KeepAlive = -1;
            CallbackMode = RedisCallbackMode.CustomChannel;
            CallbackChannel = "Aricie:Remove";
            CallbackChannelIncludeFingerPrint = true;
            SyncTimeout = 1000;
            CommandMap = new SerializableDictionary<string, string>();
            TieBreaker = "__Booksleeve_TieBreak";
            WriteBuffer = 4096;
            RedisVersion = new Version(2, 8, 0);
            Proxy = StackExchange.Redis.Proxy.None;

        }


        /// <summary>
        /// The client name to use for all connections
        /// 
        /// </summary>
        [SortOrder(0)]
        [ExtendedCategory("RedisSettings")]
        public string ClientName { get; set; }

       
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public int DbNumber { get; set; }

        /// <summary>
        /// The password to use to authenticate with the server
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public string Password { get; set; }

        /// <summary>
        /// Specifies the way cache removal callbacks are handled. a custom channel can be subscribed with events published when removal commands are issued, 
        /// or keyspace notifications can be used when enabled (see http://redis.io/topics/notifications)
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public RedisCallbackMode CallbackMode { get; set; }

        /// <summary>
        /// Sets the name of the custom channel used for callbacks subscriptions
        /// </summary>
        [ConditionalVisible("CallbackMode", false, true, RedisCallbackMode.CustomChannel)]
        [ExtendedCategory("RedisSettings")]
        public string CallbackChannel { get; set; }

        [ConditionalVisible("CallbackMode", false, true, RedisCallbackMode.CustomChannel)]
        [ExtendedCategory("RedisSettings")]
        public bool CallbackChannelIncludeFingerPrint { get; set; }

        /// <summary>
        /// Specifies the time in seconds at which connections should be pinged to ensure validity
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public int KeepAlive { get; set; }

        /// <summary>
        /// Specifies the time in milliseconds that the system should allow for synchronous operations
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public int SyncTimeout { get; set; }


        /// <summary>
        /// Tie-breaker used to choose between masters (must match the endpoint exactly)
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public string TieBreaker { get; set; }


        /// <summary>
        /// The size of the output buffer to use
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public int WriteBuffer { get; set; }

        /// <summary>
        /// Indicates whether the connection should be encrypted
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public bool UseSsl { get; set; }

        /// <summary>
        /// The target-host to use when validating SSL certificate; setting a value here enables SSL mode
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        [ConditionalVisible("UseSsl")]
        public string SslHost { get; set; }


        /// <summary>
        /// Indicates whether admin operations should be allowed
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public bool AllowAdmin { get; set; }


        /// <summary>
        /// Gets or sets whether connect/configuration timeouts should be explicitly notified via a TimeoutException
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public bool AbortOnConnectFail { get; set; }

        [ExtendedCategory("RedisSettings")]
        public Proxy Proxy { get; set; }

        /// <summary>
        /// The server version to assume
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public SerializableVersion RedisVersion { get; set; }


        [ExtendedCategory("RedisSettings")]
        public SerializableDictionary<string, string> CommandMap { get; set; }

        /// <summary>
        /// Automatically encodes and decodes channels
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public string ChannelPrefix { get; set; }



        /// <summary>
        /// Channel to use for broadcasting and listening for configuration change notification
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public string ConfigurationChannel { get; set; }
       


        /// <summary>
        /// Indicates whether endpoints should be resolved via DNS before connecting
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public bool ResolveDns{ get; set; }
        

        /// <summary>
        /// The service name used to resolve a service via sentinel
        /// 
        /// </summary>
        [ExtendedCategory("RedisSettings")]
        public string ServiceName{ get; set; }

       
    }
}
